package com.code.coinprice.handlers.route;

import com.code.coinprice.consts.CommonConstant;
import com.code.coinprice.managers.CoinPriceManager;
import com.code.coinprice.models.CoinPriceSource;
import com.code.coinprice.models.RelativeCoinPrice;
import com.code.coinprice.services.CoinPriceSourceRouteService;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 相关币种调用失败路由调用其他币种平台的处理器
 */
@Component("coinPriceInvokeApiErrorHandler")
public class CoinPriceInvokeApiErrorHandler {

    @Resource
    private CoinPriceSourceRouteService coinPriceSourceRouteService;

    @Resource
    private CoinPriceManager coinPriceManager;

    public List<RelativeCoinPrice> getCoinPriceList(CoinPriceSource coinPriceSource) {
        String source = coinPriceSource.getSource();
        CoinPriceInvokeHandler coinPriceInvokeHandler = getCoinPriceInvokeHandler(source);
        return coinPriceInvokeHandler.getCoinPriceList(coinPriceSource);
    }

    public String getCoinPrice(String source, String coinType) {
        CoinPriceInvokeHandler coinPriceInvokeHandler = getCoinPriceInvokeHandler(source);
        return coinPriceInvokeHandler.getCoinPrice(source, coinType);
    }

    /**
     * 通过职责链模式链式调用
     */
    private CoinPriceInvokeHandler getCoinPriceInvokeHandler(String source) {
        CoinPriceInvokeHandler coinPriceInvokeHandler = coinPriceManager.getApplicationContext().getBean(source.toLowerCase() + CommonConstant.COIN_PRICE_INVOKE_BEAN_NAME_SUFFIX, CoinPriceInvokeHandler.class);
        List<String> nextSourceList = new ArrayList<>();
        nextSourceList = coinPriceSourceRouteService.getNextCoinPriceSourceListBySourceOnInvokeApiError(nextSourceList, source.toUpperCase());
        if (!CollectionUtils.isEmpty(nextSourceList)) {
            CoinPriceInvokeHandler parentCoinPriceInvokeHandler = null;
            CoinPriceInvokeHandler subCoinPriceInvokeHandler;
            for (String nextSource : nextSourceList) {
                subCoinPriceInvokeHandler = coinPriceManager.getApplicationContext().getBean(nextSource.toLowerCase() + CommonConstant.COIN_PRICE_INVOKE_BEAN_NAME_SUFFIX, CoinPriceInvokeHandler.class);
                if (parentCoinPriceInvokeHandler == null) {
                    coinPriceInvokeHandler.setCoinPriceInvokeHandler(subCoinPriceInvokeHandler);
                } else {
                    parentCoinPriceInvokeHandler.setCoinPriceInvokeHandler(subCoinPriceInvokeHandler);
                }
                parentCoinPriceInvokeHandler = subCoinPriceInvokeHandler;
            }
        }
        return coinPriceInvokeHandler;
    }

}
